//
//  TSCViewController.m
//  Tsc_IOS
//
//  Created by Rio on 15-4-30.
//  Copyright (c) 2015年 idream. All rights reserved.
//
//
// TODO 无法一次性关闭所有键盘？
// TODO storyboard的本地化？
// TODO UD必须使用synchronize()方法
// TODO Reg2界面右上按钮的白色重新登录小箭头无法显示？！
// TODO 所有的TextField等默认提示内容，都应该用代码控制，而不在Storyboard中写死
// TODO 所有通过Storyborad创建的UI元素，如果屏幕大小变了，都将不正常显示
// TODO 所有输入项都提取出来，不要用_inputDic直接获取
// TODO 占用内存问题
// TODO UIImageView imageNamed的内存消耗问题（暂时全部都用96x96尺寸的icon）
// TODO 解决所有的warning
// TODO 解决界面布局问题
// TODO 重新编写MyGCSelector
// TODO 重新编写MyDialog
// BUG  MyToast高度没了？显示不出来
// BUG  如果MySpinner的table显示的比较慢，当要显示时，已经进入下一个界面了，则会在下一个界面显示出来，而不是上一个界面
// TODO MySpinner、MyAutoCompleteSearchBar，是否需要用constraint替换realyoutUI()？

// -- TODO 如果不用延迟替换根，那么所有进入APP的首次显示界面（比如顾客首界面），都需要先pop一个登录界面，作为可能返回的父界面（仅代码控制pop，而不是返回箭头）
// -- TODO 计算UI元素时不要用int，而使用CGFloat
// -- TODO 如果只改变宽高不改变位置，应该用bound
// xx TODO 能否重写nvc的push()方法？支持动画切换完成后的回调？
// -- TODO @property 各类属性该如何使用weak/strong/copy/retain？
// -- TODO autolayout到底是什么东西？outlet？IBOutlet和IBAction？
// -- TODO 所有自定义的类属性，必须以_开头，而不是m
// -- TODO 方法命名，第一个参数到底是什么？现在没有提示
// -- TODO xib如何能不指定类？以便通用？
// xx TODO 目前常量定义的机制十分不好
// -- TODO VC的跳转方法。如果在非主线程中进行跳转，下一个VC中执行的UI代码，也会在主线程中吧？
// -- TODO 图片三层缓存机制
// -- TODO TSCMyHttpUtil post的回调设计并不好，还有很多解析的重复代码，还需要进一步封装
// -- TODO Sqlite多线程问题
// -- TODO 源文件编码问题
// -- TODO xx_P1/P2的命名规则，及DBUtil中方法的命名规则。安卓和IOS的还不太一样
// -- TODO 网络情况判断
// -- TODO 修改MyDBUtil中的tableName为常量
// -- TODO encoding问题
// -- TODO NSLog中报错，尽量体现报错信息，比如&error、__function__之类的，要有一个规范
// -- TODO 如何保证APP_DB只运行一次？
// xx TODO 常量内部类？
// -- TODO Constants冲突问题
// -- TODO NSLog是否可以区分等级？这样在命令行中看得清楚一些
// TODO addConstraint(s)()方法过时了，应该修改掉
// TODO 所有常量定义，应该都加上TSC前缀
// TODO 如何能快速定位到一个vc？比如A->B->C->D，然后从D->B
// TODO nvcBar左上方的返回按钮，能否自定义直接返回到某个vc？而不是仅仅只返回一层？
// -- TODO 将postWithUrl/getWithUrl改为main线程中执行
// TODO 导购首界面：云推注册
// TODO 导购首界面：APP更新
// TODO 将所有block的定义，都抽象出来，或者如果不能抽象，则加上TSC前缀
// TODO 将所有常量等的定义，都加上TSC前缀，以便和IOS类库进行区分
#import "TSCVCWelcome.h"
#import "TSCSDK.h"
#import "TSCVCLogin.h"
#import "TSCVCCreateShopGatherInfo.h"
#import "TSCVCTest.h"
#import <AssetsLibrary/AssetsLibrary.h>


// 日志常量（注：可能会覆盖其他头文件中定义的）
#define LOG_PREFIX @"欢迎界面获取服务器信息时，"

@interface TSCVCWelcome () {
    NSInteger _userId;
    NSString * _loginKey;
    
	bool _isServerResponse;// 服务器是否成功返回（至于广告图片是下载成功、还是下载失败，需要通过mIsAdPicSuccess确定）
	bool _isAdPicSuccess;// 广告图片下载/准备成功
    
    NSInteger _dbVerGoodsClassApp;
    NSInteger _dbVerGoodsClassSer;
    
    NSInteger	_maxSelectableGoodsClassNumApp;
    NSInteger	_maxSelectableGoodsClassNumSer;
    
    NSInteger _dbVerCityApp;
    NSInteger _dbVerCitySer;
    
    NSString * _adPicUrl;
    UIImageView * _ivAd;
    
}
@end

@implementation TSCVCWelcome


- (void)viewDidLoad
{
    [super viewDidLoad];

    // 隐藏nvb
    [[self navigationController]setNavigationBarHidden:YES];
    
    
//    TSCVCTest *vcTest = [TSCVCTest vcTestWithStoryBoard];
//    [[self navigationController] pushViewController:vcTest animated:YES];
//    return;
    
    
//        NSURL * url = [NSURL URLWithString:@"assets-library://asset/asset.JPG?id=F9007CC9-05DC-4916-B723-1DECC562119C&ext=JPG"]; // 大：横
////    NSURL * url = [NSURL URLWithString:@"assets-library://asset/asset.JPG?id=7A88D41A-2E22-40C6-B150-49EAED51E613&ext=JPG"]; // 大：竖
////        NSURL * url = [NSURL URLWithString:@"assets-library://asset/asset.JPG?id=93DC1E12-C389-479F-9993-2F4B43F97E0A&ext=JPG"]; // 小：横
////        NSURL * url = [NSURL URLWithString:@"assets-library://asset/asset.JPG?id=4CFC0C6D-4239-47D6-98C2-0C307373881A&ext=JPG"]; // 小：竖
//    
//    ALAssetsLibrary * library = [[ALAssetsLibrary alloc]init];
//    [library assetForURL:url resultBlock:^(ALAsset *asset) {
//        ALAssetRepresentation *representation = [asset defaultRepresentation];
//        
//        CGFloat scale = representation.scale;
//        UIImageOrientation orientation = (UIImageOrientation)representation.orientation; // 默认1.0f
//        CGImageRef imgRef = representation.fullResolutionImage; // 默认0
//        UIImage * imageFromAsset = [[UIImage alloc]initWithCGImage:imgRef scale:scale orientation:orientation];
//        
//        
//        // 进入相片编辑vc
//        TSCVCPhotoEditor * vcPhotoEditor = [TSCVCPhotoEditor vcPhotoEditorWithStoryboard];
//        vcPhotoEditor.callbackAfterImageEdited = ^(UIImage * imageEdited) {
//            
//            // TODO delete
//            UIImageWriteToSavedPhotosAlbum (imageEdited, nil, nil , nil);
//            NSLog(@"TODO 已裁剪的相片保存在相册了哈哈！%i", arc4random());
//            
//            // TODO 应该有一个回调函数
//            
//            // 返回上一个VC
//            //        [self.navigationController popViewControllerAnimated:YES];
//        };
//        [[self navigationController] pushViewController:vcPhotoEditor animated:YES];
//        
//        // VC间传递参数
//        NSDictionary * inputDic = [NSDictionary dictionaryWithObject:imageFromAsset forKey:AEKI_UIIMAGE];
//        [[NSNotificationCenter defaultCenter] addObserver:vcPhotoEditor selector:@selector(SELECTOR_GET_VC_INPUT) name:UI_VC_NAME_PHOTO_EDITOR object:nil];
//        [[NSNotificationCenter defaultCenter] postNotificationName:UI_VC_NAME_PHOTO_EDITOR object:inputDic];
//        
//    } failureBlock:^(NSError *error) {
//        NSLog(@"通过url获得图片asset失败！");
//    }];
//    
//    return;
    

    
//    // 进入创建店铺vc
//    TSCVCCreateShopGatherInfo * vcCreateShop = [TSCVCCreateShopGatherInfo vcCreateShopWithStoryboard];
//    [[self navigationController] pushViewController:vcCreateShop animated:YES];
//    
//    // VC间传递参数
//    NSDictionary * inputDic = [NSDictionary dictionaryWithObject:[NSNumber numberWithLong:1 ] forKey:AEKI_CITY_ID];
//    [[NSNotificationCenter defaultCenter] addObserver:vcCreateShop selector:@selector(SELECTOR_GET_VC_INPUT) name:UI_VC_NAME_CREATE_SHOP_GATHER_INFO object:nil];
//    [[NSNotificationCenter defaultCenter] postNotificationName:UI_VC_NAME_CREATE_SHOP_GATHER_INFO object:inputDic];
//    
//    return;
    
    
    

    [TSCVCWelcome class];

    
    // 获得md
    // 注：当用户从未在该设备上登录过时，取出的值均为空
    _userId = [_ud integerForKey:UD_USER_ID];
    _loginKey = [_ud stringForKey:UD_LOGIN_KEY];
    
    // 初始化属性
    _isServerResponse = _isAdPicSuccess = FALSE;
    
    // 从server获得商品分类的最新信息，并和APP_DB的版本号进行比较。如果需要更新，则更新至APP_DB
    [self getServerAppInitData_PP1];
    
    // 新线程等待一段时间后，跳转至下一个界面
    [self performSelectorInBackground:@selector(waitStartupApp_P1) withObject:nil];
    
}

//// 点击空白区域收回键盘
//- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//    [spCity resignFirstResponder];
//}

- (void) btnClicked {
    NSLog(@"WElcome中按钮被点击了...");
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/* private */ - (void) getServerAppInitData_PP1 {
    // 检查网络环境
    if([TSCMyNetworkUtil checkNetwork] == false) {
        NSLog(@"[W]%@网络不可用！", LOG_PREFIX);
        return;
    };
    
    // 从APP_DB中取出：
    // 商品分类版本号
    // 所允许选择的商品分类最大数量
    // 城市版本号
    NSDictionary * dicSysConfig = [TSCMyDBUtil getSysConfigValueBatch_1: [NSArray arrayWithObjects:DB_SYS_CONFIG_KEY_DB_VERSION_GOODS_CLASS, DB_SYS_CONFIG_KEY_MAX_SELECTABLE_GOODS_CLASS, DB_SYS_CONFIG_KEY_DB_VERSION_CITY, nil]];
    _dbVerGoodsClassApp = [[dicSysConfig objectForKey:DB_SYS_CONFIG_KEY_DB_VERSION_GOODS_CLASS]intValue];
    _maxSelectableGoodsClassNumApp = [[dicSysConfig objectForKey:DB_SYS_CONFIG_KEY_MAX_SELECTABLE_GOODS_CLASS]intValue];
    _dbVerCityApp = [[dicSysConfig objectForKey:DB_SYS_CONFIG_KEY_DB_VERSION_CITY]intValue];
    
    // 拼装请求
    NSMutableDictionary * reqDic = [[NSMutableDictionary alloc] init];
    [reqDic setObject:[NSNumber numberWithLong:_dbVerGoodsClassApp] forKey:@"db_version_goods_class"];
    [reqDic setObject:[NSNumber numberWithLong:_dbVerCityApp ] forKey:@"db_version_city"];
    // 注：有可能user_id和login_key为空值
    [reqDic setValue:[NSNumber numberWithLong:_userId] forKey:UD_USER_ID];
    [reqDic setValue:_loginKey forKey:UD_LOGIN_KEY];
    
    // 发送请求
    [TSCMyHttpUtil postWithUrl:URL_GET_APP_INIT_DATA dictionary:reqDic completionHandler:^(ServerRespType serverRespType, NSString * respString, NSDictionary *respDictionary, NSInteger code, NSString *msg, NSDictionary *contentDictionary) {
        // 服务器返回错误处理
        switch (serverRespType) {
            case ServerRespTypeSuccess:
                break;
            case ServerRespTypeErrNil:
            case ServerRespTypeErrJson: {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [TSCMyUIUtil popErrWithResourceKey:@"err_web_server_unavailable"];
                });
                return;
            }
            case ServerRespTypeErrCode:{
                dispatch_async(dispatch_get_main_queue(), ^{
                    [TSCMyUIUtil popErrWithString:msg];
                });
                return;
            }
            default:
                dispatch_async(dispatch_get_main_queue(), ^{
                    [TSCMyUIUtil popErrWithResourceKey:@"err_system"];
                });
                return;
        }
        
        // 更新标识位
        _isServerResponse = true;
        
        // 解析服务器返回
        _dbVerGoodsClassSer = [[contentDictionary objectForKey:@"db_version_goods_class"]intValue];
        _maxSelectableGoodsClassNumSer = [[contentDictionary objectForKey:@"max_selectable_goods_class_num"]intValue];
        _dbVerCitySer = [[contentDictionary objectForKey:@"db_version_city"]intValue];
        _adPicUrl = [contentDictionary objectForKey:@"welcome_ad_pic_url"]; // 如果没有返回空白字符串
        
        // 方法一：回到主线程继续，需创建串行队列
        //        [self performSelectorOnMainThread:@selector(getServerAppInitData_PP2:) withObject:contentDictionary waitUntilDone:YES];
        // 方法二：在当前异步线程中继续后续逻辑，无需创建串行队列（注：因为不涉及UI操作，所以可以依然在异步线程中继续）
        [self getServerAppInitData_PP2:(contentDictionary)];
    }];
}

/* private */ - (void) getServerAppInitData_PP2:(NSDictionary *) contentDic {
    // 为避免多线程同时操作数据库，创建串行队列
    //    dispatch_queue_t dbQueue = dispatch_queue_create("OPERATE_DB_QUEUE", DISPATCH_QUEUE_SERIAL);
    
    // ========== （1）更新商品分类信息
    // 注：仅当版本号显示需要更新时才更新
    if (_dbVerGoodsClassApp < _dbVerGoodsClassSer) {
        NSLog(@"[D]%@获得server商品分类成功，根据版本号判断需要更新商品分类[旧版本号:%li,新版本号:%li]。正在更新...", LOG_PREFIX, _dbVerGoodsClassApp, _dbVerGoodsClassSer);
        
        // 解析商品分类列表
        NSArray * gcArray = [contentDic objectForKey:@"goods_class_list"];
        
        // 更新商品分类
        //        dispatch_async(dbQueue, ^{
        [TSCMyDBUtil updateGoodsClassWithVersionNum_1:_dbVerGoodsClassSer gcArray:gcArray];
        //        });
    } else {
        NSLog(@"[D]%@获得server商品分类成功，但根据版本号判断无需更新商品分类[旧版本号:%li,新版本号:%li]。", LOG_PREFIX, _dbVerGoodsClassApp,_dbVerGoodsClassSer );
    }
    
    // ========== （2）更新允许选择的最大商品数量
    // 注：仅当两者不一致时才更新
    if (_maxSelectableGoodsClassNumApp != _maxSelectableGoodsClassNumSer) {
        NSLog(@"[D]%@获得server商品分类最大可选择数量成功，根据新旧值判断，需要更新允许选择商品分类数量的最大值[旧:%li,新:%li]。正在更新...", LOG_PREFIX, _maxSelectableGoodsClassNumApp, _maxSelectableGoodsClassNumSer);
        
        // 更新可选商品分类最大数量
        //        dispatch_async(dbQueue, ^{
        [TSCMyDBUtil updateSysConfigValueWithKey_1:DB_SYS_CONFIG_KEY_MAX_SELECTABLE_GOODS_CLASS value:[NSString stringWithFormat:@"%li", _maxSelectableGoodsClassNumSer]];
        //        });
    } else {
        NSLog(@"[D]%@获得server商品分类最大可选择数量成功，但根据新旧值判断，无需要更新允许选择商品分类数量的最大值[旧:%li,新:%li]。",LOG_PREFIX, _maxSelectableGoodsClassNumApp, _maxSelectableGoodsClassNumSer);
    }
    
    // ========== （3）更新城市信息
    // 注：仅当版本号显示需要更新时才更新
    if (_dbVerCityApp < _dbVerCitySer) {
        NSLog(@"[D]%@获得server城市信息成功，根据版本号判断需要更新城市信息[旧版本号:%li,新版本号:%li]。正在更新...", LOG_PREFIX, _dbVerCityApp, _dbVerCitySer);
        
        // 解析城市列表
        NSArray * cityArray = [contentDic objectForKey:@"city_list"];
        
        // 更新城市信息
        [TSCMyDBUtil updateCityWithVersionNum_1:_dbVerCitySer cityArray:cityArray];
    } else {
        NSLog(@"[D]%@获得server城市信息成功，但根据版本号判断无需更新商品分类[旧版本号:%li,新版本号:%li]。", LOG_PREFIX, _dbVerGoodsClassApp, _dbVerGoodsClassSer);
    }
    
    // ========== （4）更新SER_DB需要与APP UD文件同步的信息
    // （4.2）导购所在店铺经营的商品分类ids。使用场景：（仅导购）创建首次回复时直接从本地加载
    NSString * guideGCIds1 = [_ud stringForKey:UD_GUIDE_GOODS_CLASS_IDS];
    NSString * guideGCIds2 = [contentDic objectForKey:@"guide_goods_class_ids"];
    // （4.3）导购所在店铺名称。使用场景：（仅导购）进入设置界面，会根据此值显示其所在的店铺
    NSString * guideShopName1 = [_ud stringForKey:UD_GUIDE_SHOP_NAME];
    NSString * guideShopName2 = [contentDic objectForKey:@"guide_shop_name"];
    // （4.4）导购是否为店长。使用场景：（仅导购）首界面右上角菜单是否显示审批
    NSInteger guideIsManager1 = [_ud integerForKey:UD_GUIDE_IS_MANAGER];
    NSInteger guideIsManager2 = [[contentDic objectForKey:@"guide_is_manager"] intValue]; // 注：如果server无返回，使用-1表示，而不能是0
    // （4.1）城市id。使用场景：顾客进入设置界面显示所在城市、顾客进入选择城市界面初始化spinner、导购进入更换店铺界面初始化spinner、导购进入更换店铺商场界面初始化spinner
    NSInteger cityId1 = [_ud integerForKey:UD_USER_CITY_ID];
    NSInteger cityId2 = [[contentDic objectForKey:@"city_id"] intValue];
    // （4.5）用户邮箱是否已通过验证。使用场景：注册后用户邮箱并未通过验证，用户在设置界面重新验证邮箱后，重新打开APP需要更新SP为“已验证”
    NSInteger isEmailValid1 = [_ud integerForKey:UD_USER_EMAIL_VALID];
    NSInteger isEmailValid2 = [[contentDic objectForKey:@"email_valid"] intValue]; // 注：如果server无返回，使用-1表示，而不能是0
    
    if ([TSCMyUtil isStringEmpty:guideGCIds2] == false && guideGCIds2 != guideGCIds1) {
        [_ud setObject:guideGCIds2 forKey:UD_GUIDE_GOODS_CLASS_IDS];
        NSLog(@"[D]%@获得server导购所在店铺经营商品分类ids[旧:%@，新:%@]成功，并准备更新至SP文件。", LOG_PREFIX, guideGCIds1 , guideGCIds2);
    }
    
    if (cityId2 != 0 && cityId2 != cityId1) {
        [_ud setObject:[NSNumber numberWithLong:cityId2] forKey:UD_USER_CITY_ID];
        NSLog(@"[D]%@获得server用户城市id[旧:%li，新:%li]成功，并更新至SP文件成功。", LOG_PREFIX, cityId1, cityId2);
    }
    
    if ([TSCMyUtil isStringEmpty:guideShopName2] == false && guideShopName2 != guideShopName1) {
        [_ud setObject:guideShopName2 forKey:UD_GUIDE_SHOP_NAME];
        NSLog(@"[D]%@获得server导购所在店铺名称[旧:%@，新:%@]成功，并更新至SP文件成功。", LOG_PREFIX, guideShopName1 ,guideShopName2);
    }
    
    if (guideIsManager2 != 0 && guideIsManager2 != guideIsManager1) {
        [_ud setObject:[NSNumber numberWithLong:guideIsManager2] forKey:UD_GUIDE_IS_MANAGER];
        NSLog(@"[D]%@获得server导购身份是否为店长[旧:%li，新:%li]成功，并更新至SP文件成功。", LOG_PREFIX, guideIsManager1, guideIsManager2);
    }
    
    if (isEmailValid2 != 0 && isEmailValid2 != isEmailValid1) {
        [_ud setObject:[NSNumber numberWithLong:isEmailValid2] forKey:UD_USER_EMAIL_VALID];
        NSLog(@"%@获得server用户邮箱是否已通过验证[旧:%li，新:%li]成功，并更新至SP文件成功。", LOG_PREFIX, isEmailValid1, isEmailValid2);
    }
    
    [_ud synchronize];
    
    
    // ========== （5）更新广告图片
    if ([TSCMyUtil isStringEmpty:_adPicUrl] == false) {
        NSLog(@"[D]%@有广告图片，并准备显示...", LOG_PREFIX);
        
        dispatch_async(dispatch_get_main_queue(), ^{
            _ivAd = [[UIImageView alloc]init];
            [_ivAd sd_setImageWithURL:[NSURL URLWithString:_adPicUrl] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                _ivAd.frame =  self.view.frame;
                _ivAd.contentMode = UIViewContentModeScaleAspectFill;
                _ivAd.alpha = 0;
                [self.view addSubview:_ivAd];
                
                // 更新标识位
                _isAdPicSuccess = true;
            }];
        });
    }
}

/* private */ - (void) waitStartupApp_P1 {
    // 两秒之后，自动进入登录界面，或者主界面
    [NSThread sleepForTimeInterval: CONFIG_WELCOME_PAGE_DISPLAY_S];
    
    // 回到主线程
    dispatch_async(dispatch_get_main_queue(), ^{
        // 服务器成功返回，并且广告图片下载/设置成功，则显示广告
        if (_isServerResponse == true && _isAdPicSuccess == true) {
            NSLog(@"[D]%@服务器成功返回，并且广告图片下载/设置成功，显示广告...", LOG_PREFIX);
            
            [UIView animateWithDuration:CONFIG_ANIMATION_DURATION_S animations:^{
                _ivAd.alpha = 1;
            } completion:^(BOOL finished) {
                [self performSelectorInBackground:@selector(waitStartupApp_P2) withObject:nil];
            }];
        }
        // 服务器返回失败，或者广告图片下载/设置不成功，则直接进入APP
        else {
            NSLog(@"[D]%@服务器返回失败，或者广告图片下载/设置不成功，直接进入APP...", LOG_PREFIX);
            
            // 由系统控制后续界面该如何跳转，并关闭当前界面
            [TSCMyUIUtil dispatchLoginUIWithVC:self ud:_ud additionalTagArray:nil];
            [TSCMyUIUtil removeVCItselfAndAllPreviousVC:self];
        }
    });
}

/* private */ - (void) waitStartupApp_P2 {
    [NSThread sleepForTimeInterval: CONFIG_WELCOME_PAGE_AD_S];
    
    // 回到主线程
    dispatch_async(dispatch_get_main_queue(), ^{
        // 由系统控制后续界面该如何跳转，并关闭当前界面
        [TSCMyUIUtil dispatchLoginUIWithVC:self ud:_ud additionalTagArray:nil];
        [TSCMyUIUtil removeVCItselfAndAllPreviousVC:self];
    });
}

//- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
//    NSLog(@"%s",__FUNCTION__);
//}
//
//- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//    NSLog(@"%s",__FUNCTION__);
//}
//
//- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
//    NSLog(@"%s",__FUNCTION__);
//}

- (void)dealloc {
    NSLog(@"TODO dealloc %@", self);
}

@end

